package com.siemens.industrial.app;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Created by qupen on 2016/11/29.
 */
public class SendMail {
    private static final ObjectMapper objectMapper = new ObjectMapper();
    private String encoding = "text/html;charset=UTF-8";
    private String sender;
    private String[] receivers;
    private String subject;
    private String message;

    private Session session;
    private Transport transport;

    public String getEncoding() {
        return encoding;
    }

    public void setEncoding(String encoding) {
        this.encoding = encoding;
    }

    public String getSender() {
        return sender;
    }

    public void setSender(String sender) {
        this.sender = sender;
    }

    public String[] getReceivers() {
        return receivers;
    }

    public void setReceivers(String[] receivers) {
        this.receivers = receivers;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public SendMail(Map<String, String> propertiesMap) throws MessagingException {
        Properties properties = new Properties();
        properties.setProperty("mail.host", propertiesMap.get("host"));
        properties.setProperty("mail.transport.protocol", "smtp");
        properties.setProperty("mail.smtp.auth", "true");
        properties.setProperty("mail.port", propertiesMap.get("port"));

        this.session = Session.getDefaultInstance(properties);

        this.transport = this.session.getTransport();
        this.transport.connect(propertiesMap.get("host"), propertiesMap.get("username"), propertiesMap.get("password"));
    }

    /**
     * send message, need set all properties before send
     * note: no cc contains, please add it if necessary
     */
    public void send() throws MessagingException {
        InternetAddress[] receiversAddress = new InternetAddress[this.receivers.length];

        for (int i = 0; i < this.receivers.length; i++) {
            receiversAddress[i] = new InternetAddress(this.receivers[i]);
        }

        MimeMessage message = new MimeMessage(this.session);
        message.setFrom(new InternetAddress(this.sender));
        message.setRecipients(Message.RecipientType.TO, receiversAddress);
        message.setSubject(this.subject, "UTF-8");
        message.setContent(this.message, this.encoding);

        this.transport.sendMessage(message, message.getAllRecipients());
        this.transport.close();
    }

    public void setMailParam(String subject, String[] receivers, String message, String sender) {
        this.sender = sender;
        this.subject = subject;
        this.receivers = receivers;
        this.message = message;
    }

    public static Map<String, String> buildMailProperties(String json) {
        Map<String, Object> mailConfig = SendMail.buildJsonToMap(json);
        Map<String, String> map = new HashMap<>();
        map.put("host", mailConfig.get("ip_address_key").toString());
        map.put("port", mailConfig.get("port_key").toString());
        map.put("username", mailConfig.get("username_key").toString());
        map.put("password", mailConfig.get("password_key").toString());
        map.put("mailAddress_key",mailConfig.get("mailAddress_key").toString());
        return map;
    }

    public static Map<String, Object> buildJsonToMap(String data) {

        Map<String, Object> map = new HashMap<>();

        // convert JSON string to Map
        try {
            map = objectMapper.readValue(data, Map.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return map;
    }
}
